home *** CD-ROM | disk | FTP | other *** search
/ Scene 96 / Scene 96 International Edition (Zyklop Software) (Disc 2) (1997).iso / misc / coding / midas060 / samples / midp_dos / midp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-01  |  15.2 KB  |  533 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <malloc.h>
  4. #include <conio.h>
  5. #include <ctype.h>
  6. #include <time.h>
  7. #include <process.h>
  8. #include "midas.h"
  9. #include "mconfig.h"
  10. #include "vu.h"
  11. #include "vga.h"
  12. #include "midp.h"
  13.  
  14.  
  15. #ifndef NOTIMER
  16. #define SCRSYNC
  17. #endif
  18.  
  19. int             numChannels = 0;        /* number of channels in module */
  20. int             activeChannel = 0;      /* active channel number */
  21.  
  22. uchar           attrDispTop = 0x4F;     /* display top message */
  23. uchar           attrMainBg = 0x70;      /* main window background */
  24. uchar           attrMainLit = 0x7F;     /* main window lit areas */
  25. uchar           attrMainShadow = 0x78;  /* main window shadow areas */
  26. uchar           attrMainBorderLit = 0x0F;   /* main window lit border */
  27. uchar           attrMainBorderSh = 0x08;    /* main window shadow border */
  28. uchar           attrChanInfoSep = 0x70;    /* channel information separator */
  29. uchar           attrChanInfo = 0x70;    /* channel information */
  30. uchar           attrSongInfoLabel = 0x7F;   /* song information label */
  31. uchar           attrSongInfo = 0x70;    /* song information */
  32. uchar           attrUsedInstName = 0x70;    /* used instrument name */
  33. uchar           attrUnusedInstName = 0x78;  /* unused instrument name */
  34. uchar           attrInstNameSeparator = 0x70;  /* instrument name separator */
  35. uchar           attrInstIndicator = 0x7E;   /* instrument used indicator */
  36. uchar           attrActChanMarker = 0x07;   /* active channel marker */
  37. uchar           attrVUMeters = 0x7A;    /* VU meters */
  38. uchar           attrVUBlank = 0x70;     /* Blank VU meters */
  39.  
  40. int             msgWindowHeight = 8;    /* message window height */
  41.  
  42. time_t          startTime;              /* total playing time */
  43. time_t          pauseTime = 0;          /* time spent paused */
  44. time_t          pauseStart;             /* start time for current pause */
  45.  
  46. int             paused = 0;             /* is playing paused? */
  47. unsigned        masterVolume = 64;      /* master volume */
  48. int             instNameMode = 0;       /* instrument name display mode */
  49. int             firstInstName = 1;      /* first instrument name on screen */
  50.  
  51. int             realVU = 1;             /* are real VU meters active? */
  52.  
  53. gmpModule       *module;                /* current playing module */
  54. gmpInformation  *info;                  /* current module playing info */
  55. int             callMP;
  56.  
  57. uchar           chMuted[32];            /* channel muted flags */
  58.  
  59. unsigned        scrSync;                /* timer screen sync value */
  60.  
  61. volatile ulong  frameCount;             /* frame counter */
  62.  
  63. void DumpHeap(void)
  64. {
  65.     static struct _heapinfo hinfo;
  66.     int         hstatus;
  67.  
  68.     hinfo._pentry = NULL;
  69.  
  70.     while ( 1 )
  71.     {
  72.         hstatus = _heapwalk(&hinfo);
  73.         if ( hstatus != _HEAPOK )
  74.             break;
  75.         if ( hinfo._useflag == _USEDENTRY )
  76.             printf("USED block at %FP of size %4.4X\n", hinfo._pentry,
  77.                 hinfo._size);
  78.         else
  79.             printf("FREE block at %FP of size %4.4X\n", hinfo._pentry,
  80.                 hinfo._size);
  81.     }
  82.  
  83.     switch ( hstatus )
  84.     {
  85.         case _HEAPEND:
  86.             printf("OK - end of heap\n\n");
  87.             break;
  88.  
  89.         case _HEAPEMPTY:
  90.             printf("OK - heap is empty\n\n");
  91.             break;
  92.  
  93.         default:
  94.             printf("ERROR - heap corrupted\n\n");
  95.     }
  96. }
  97.  
  98.  
  99.  
  100.  
  101. void CommandChecksum(void)
  102. {
  103.     ulong       sum = 0;
  104.     int         i;
  105.  
  106.     for ( i = 0; i < gmpNumCommands; i++ )
  107.         sum += (ulong) gmpTick0CommandsPT[i];
  108.     printf("%08X, ", sum);
  109.     for ( i = 0; i < gmpNumCommands; i++ )
  110.         sum += (ulong) gmpContCommandsPT[i];
  111.     printf("%08X\n", sum);
  112.     fflush(stdout);
  113. }
  114.  
  115.  
  116.  
  117. void CALLING PreVR(void)
  118. {
  119.     frameCount++;
  120. }
  121.  
  122.  
  123.  
  124. void WaitFrame(void)
  125. {
  126. #ifdef SCRSYNC
  127.     ulong       oldFrameCount = frameCount;
  128.  
  129.     return;
  130.  
  131.     while ( oldFrameCount == frameCount );
  132. #else
  133.     vgaWaitVR();
  134.     vgaWaitDE();
  135. #endif
  136. }
  137.  
  138.  
  139.  
  140. int CALLING MakeMeter(sdSample *sdsmp, gmpSample *gmpsmp)
  141. {
  142.     return vuPrepare(sdsmp, gmpsmp->sdHandle - 1);
  143. }
  144.  
  145.  
  146. int main(int argc, char *argv[])
  147. {
  148.     int         error;
  149.     int         quit = 0;
  150.     int         key, i;
  151.     int         doConfig = 0;
  152.     static fileHandle  f;
  153.     static uchar       buf[48];
  154.     static int  panning;
  155.  
  156.  
  157. //    puts("Press any");
  158. //    getch();
  159.  
  160.     setvbuf(stdout, NULL, _IONBF, 0);
  161.  
  162.     midasSetDefaults();
  163.  
  164.     if ( argc < 2 )
  165.     {
  166.         puts("Usage:   MIDP <module> [options]\n");
  167.         puts("Options: -c Manual sound card configuration");
  168.         exit(EXIT_SUCCESS);
  169.     }
  170.  
  171.     if ( argc > 2 )
  172.     {
  173.         if ( ((argv[2][0] == '-') || (argv[2][0] == '/')) &&
  174.              ((argv[2][1] == 'c') || (argv[2][1] == 'C')) )
  175.             doConfig = 1;
  176.     }
  177.  
  178.     midasSetDefaults();
  179.  
  180.     if ( doConfig )
  181.         midasConfig();
  182.  
  183.     midasDisableEMS = 1;
  184. //    midasOutputMode |= sdMono;
  185. //    midasOutputMode &= (~sdStereo);
  186. //    midasSDNumber = 2;
  187.  
  188.     InitDisplay();
  189.     DrawScreen();
  190.  
  191. #ifdef SCRSYNC
  192.     if ( (error = tmrGetScrSync(&scrSync)) != OK )
  193.         midasError(error);
  194. #endif
  195.  
  196.     midasInit();
  197.  
  198.     if ( realVU )
  199.         if ( (error = vuInit()) != OK )
  200.             midasError(error);
  201.  
  202. //#ifdef SCRSYNC
  203. //    if ( (error = tmrSyncScr(scrSync, &PreVR, NULL, NULL)) != OK )
  204. //        midasError(error);
  205. //#endif
  206.  
  207.     printf("%P\n", dsmMixBuffer);
  208.  
  209.     printf("Using %s\n%s, using port %X, IRQ %i and DMA %i\n",
  210.         midasSD->name, midasSD->cardNames[midasSD->cardType-1],
  211.         midasSD->port, midasSD->IRQ, midasSD->DMA);
  212.  
  213.     /* Read first 48 bytes of module: */
  214.     if ( (error = fileOpen(argv[1], fileOpenRead, &f)) != OK )
  215.         midasError(error);
  216.     if ( (error = fileRead(f, buf, 48)) != OK )
  217.         midasError(error);
  218.     if ( (error = fileClose(f)) != OK )
  219.         midasError(error);
  220.  
  221.     if ( mMemEqual(buf, "Extended Module:", 16) )
  222.     {
  223.         puts("Loading Fasttracker 2 module");
  224.         if ( realVU )
  225.         {
  226.             if ( (error = gmpLoadXM(argv[1], 1, &MakeMeter, &module)) != OK )
  227.                 midasError(error);
  228.         }
  229.         else
  230.         {
  231.             if ( (error = gmpLoadXM(argv[1], 1, NULL, &module)) != OK )
  232.                 midasError(error);
  233.         }
  234.     }
  235.     else
  236.     {
  237.         if ( mMemEqual(buf+44, "SCRM", 4) )
  238.         {
  239.             puts("Loading Screamtracker 3 module");
  240.             if ( realVU )
  241.             {
  242.                 if ( (error = gmpLoadS3M(argv[1], 1, &MakeMeter, &module))
  243.                     != OK )
  244.                     midasError(error);
  245.             }
  246.             else
  247.             {
  248.                 if ( (error = gmpLoadS3M(argv[1], 1, NULL, &module)) != OK )
  249.                     midasError(error);
  250.             }
  251.         }
  252.         else
  253.         {
  254.             puts("Loading Protracker module");
  255.             if ( realVU )
  256.             {
  257.                 if ( (error = gmpLoadMOD(argv[1], 1, &MakeMeter, &module))
  258.                     != OK )
  259.                     midasError(error);
  260.             }
  261.             else
  262.             {
  263.                 if ( (error = gmpLoadMOD(argv[1], 1, NULL, &module)) != OK )
  264.                     midasError(error);
  265.             }
  266.         }
  267.     }
  268.     numChannels = dispChannels = module->numChannels;
  269.  
  270.     puts("Playing");
  271.     midasPlayModule(module, 0);
  272.  
  273.     DrawScreen();
  274.     DrawSongInfo();
  275.     startTime = time(NULL);
  276.  
  277. #ifdef SCRSYNC
  278.     if ( (error = tmrSyncScr(scrSync, &PreVR, NULL, NULL)) != OK )
  279.         midasError(error);
  280. #endif
  281.  
  282.     /* Clear channel muted flags: */
  283.     for ( i = 0; i < 32; i++ )
  284.         chMuted[i] = 0;
  285.  
  286.     while ( !quit )
  287.     {
  288.         WaitFrame();
  289.  
  290. #ifdef BORDERS
  291.         vgaSetBorder(15);
  292. #endif
  293. #ifdef NOTIMER
  294.         if ( (error = midasSD->StartPlay()) != OK )
  295.             midasError(error);
  296.         do
  297.         {
  298. #ifdef BORDERS
  299.             vgaSetBorder(3);
  300. #endif
  301.             if ( (error = midasSD->Play(&callMP)) != OK )
  302.                 midasError(error);
  303. #ifdef BORDERS
  304.             vgaSetBorder(13);
  305. #endif
  306.             if ( callMP )
  307.             {
  308. //                CommandChecksum();
  309.                 if ( (error = gmpPlay()) != OK )
  310.                     midasError(error);
  311.             }
  312.         } while ( callMP && (midasSD->tempoPoll == 0) );
  313. //        gmpPlay();
  314. #endif
  315. #ifdef BORDERS
  316.         vgaSetBorder(1);
  317. #endif
  318.  
  319.         if ( (error = gmpGetInformation(midasPlayHandle, &info)) != OK )
  320.             midasError(error);
  321.  
  322.         UpdateScreen();
  323. #ifdef BORDERS
  324.         vgaSetBorder(0);
  325. #endif
  326.  
  327.         if ( kbhit() )
  328.         {
  329.             key = mGetKey();                /* read keypress */
  330.             if ( key < 0x100 ) key = toupper ( (char) key );
  331.  
  332.             switch ( key )
  333.             {
  334.                 case 27:
  335.                     quit = 1;
  336.                     break;
  337.  
  338.                 case 9:
  339.                     instNameMode ^= 1;
  340.                     DrawScreen();
  341.                     DrawSongInfo();
  342.                     break;
  343.  
  344.                 case 'D':
  345. #ifdef SCRSYNC
  346.                     if ( (error = tmrStopScrSync()) != OK )
  347.                         midasError(error);
  348. #endif
  349.                     spawnl(P_WAIT, mGetEnv("COMSPEC"), NULL);
  350.                     InitDisplay();
  351.                     DrawScreen();
  352.                     DrawSongInfo();
  353. #ifdef SCRSYNC
  354.                     if ( (error = tmrSyncScr(scrSync, &PreVR, NULL, NULL))
  355.                         != OK )
  356.                         midasError(error);
  357. #endif
  358.                     break;
  359.  
  360.                 case '-':
  361.                     if ( masterVolume > 0 )
  362.                         masterVolume--;
  363.                     if ( (error = midasSD->SetMasterVolume(masterVolume))
  364.                         != OK )
  365.                         midasError(error);
  366.                     break;
  367.  
  368.                 case '+':
  369.                     if ( masterVolume < 64 )
  370.                         masterVolume++;
  371.                     if ( (error = midasSD->SetMasterVolume(masterVolume))
  372.                         != OK )
  373.                         midasError(error);
  374.                     break;
  375.  
  376.                     case 0x14d:         /* Right arrow */
  377. incPosition:            gmpHandle->position++;
  378.  
  379.                         /* Check if we reached song length, and if so, jump to
  380.                             restart position: */
  381.                         if (gmpHandle->position > gmpHandle->songEnd)
  382.                         {
  383.                             gmpHandle->position = gmpHandle->restartPos;
  384.                         }
  385.  
  386.                         /* Get the pattern number for new position: */
  387.                         if (( gmpCurModule->songData[gmpHandle->position]
  388.                             == 0xfffe ) || (gmpCurModule->
  389.                             songData[gmpHandle->position] == 0xffff))
  390.                             goto incPosition;
  391.  
  392.                         gmpHandle->pattern = gmpCurModule->
  393.                             songData[gmpHandle->position];
  394.                         gmpHandle->row = 0;
  395.                         gmpHandle->playPtr = NULL;
  396.                         break;
  397.  
  398.                     case 0x14b:         /* Left arrow */
  399. decPosition:            gmpHandle->position--;
  400.                         if ( gmpHandle->position >= gmpCurModule->songLength )
  401.                             gmpHandle->position = gmpCurModule->songLength-1;
  402.                         if ( (gmpCurModule->songData[gmpHandle->position]
  403.                             == 0xfffe ) || ( gmpCurModule->
  404.                             songData[gmpHandle->position] == 0xffff ) )
  405.                             goto decPosition;
  406.  
  407.                         gmpHandle->pattern = gmpCurModule->
  408.                             songData[gmpHandle->position];
  409.                         gmpHandle->row = 0;
  410.                         gmpHandle->playPtr = NULL;
  411.                         break;
  412.  
  413.                     case 0x151:         /* Page down */
  414.                         if ( firstInstName < gmpHandle->module->numInsts )
  415.                         {
  416.                             firstInstName++;
  417.                             DrawInstNames();
  418.                         }
  419.                         break;
  420.  
  421.                     case 0x149:         /* Page up */
  422.                         if ( firstInstName > 1 )
  423.                         {
  424.                             firstInstName--;
  425.                             DrawInstNames();
  426.                         }
  427.                         break;
  428.  
  429.                     case 0x148:         /* Up arrow */
  430.                         if ( activeChannel > 0 )
  431.                             activeChannel--;
  432.                         break;
  433.  
  434.                     case 0x150:         /* Down arrow */
  435.                         if ( activeChannel < (numChannels-1) )
  436.                             activeChannel++;
  437.                         break;
  438.  
  439.                     case 'T':           /* T - toggle channel mute on/off */
  440.                         chMuted[activeChannel] ^= 1;
  441.                         if ( (error = midasSD->MuteChannel(activeChannel,
  442.                             chMuted[activeChannel])) != OK )
  443.                             midasError(error);
  444.                         break;
  445.  
  446.                     case 'M':
  447.                         if ( (error = midasSD->SetPanning(activeChannel,
  448.                             panMiddle)) != OK )
  449.                             midasError(error);
  450.                         break;
  451.  
  452.                     case 'L':
  453.                         if ( (error = midasSD->SetPanning(activeChannel,
  454.                             panLeft)) != OK )
  455.                             midasError(error);
  456.                         break;
  457.  
  458.                     case 'R':
  459.                         if ( (error = midasSD->SetPanning(activeChannel,
  460.                             panRight)) != OK )
  461.                             midasError(error);
  462.                         break;
  463.  
  464.                     case 'U':
  465.                         if ( (error = midasSD->SetPanning(activeChannel,
  466.                             panSurround)) != OK )
  467.                             midasError(error);
  468.                         break;
  469.  
  470.                     case ',':
  471.                         if ( (error = midasSD->GetPanning(activeChannel,
  472.                             &panning)) != OK )
  473.                             midasError(error);
  474.                         if ( panning > panLeft )
  475.                         {
  476.                             panning--;
  477.                             if ( (error = midasSD->SetPanning(activeChannel,
  478.                                 panning)) != OK )
  479.                                 midasError(error);
  480.                         }
  481.                         break;
  482.  
  483.                     case '.':
  484.                         if ( (error = midasSD->GetPanning(activeChannel,
  485.                             &panning)) != OK )
  486.                             midasError(error);
  487.                         if ( panning < panRight )
  488.                         {
  489.                             panning++;
  490.                             if ( (error = midasSD->SetPanning(activeChannel,
  491.                                 panning)) != OK )
  492.                                 midasError(error);
  493.                         }
  494.                         break;
  495.             }
  496.         }
  497.     }
  498.  
  499.     printf("\n");
  500.  
  501.     puts("0");
  502.     midasStopModule(module);
  503.  
  504.     puts("0.5");
  505.     if ( realVU )
  506.     {
  507.         for ( i = 0; i < MAXSAMPLES; i++ )
  508.             if ( (error = vuRemove(i)) != OK )
  509.                 midasError(error);
  510.     }
  511.  
  512.     puts("1");
  513.     if ( (error = gmpFreeModule(module)) != OK )
  514.         midasError(error);
  515.  
  516.     puts("1.5");
  517.     if ( realVU )
  518.     {
  519.         if ( (error = vuClose()) != OK )
  520.             midasError(error);
  521.     }
  522.  
  523.     puts("2");
  524.     midasClose();
  525.  
  526.     DumpHeap();
  527. #ifdef DEBUG
  528.     errPrintList();
  529. #endif
  530.  
  531.     return 0;
  532. }
  533.